"""
Case Type   : 资源池化
Case Name   : 资源池化场景下, 三节点均有业务，踢出一个节点后并且重新加入
Create At   : 2024-04-07
Owner       : songshixuan
Description :
    1、查看集群状态 cm_ctl query -Cv
    2、开始运行tpcc
    3、踢出备1节点
    4、查看各个节点业务
    5、对节点进行重新启动
    6、恢复集群原始状态
Expect      :
    1、集群状态正常，数据库节点状态正常
    2、tpcc运行成功，三节点正常开始业务
    3、踢出备一节点成功
    4、各个节点业务正常不中断
    5、对节点进行重新启动，节点状态正常，业务不中断；
    6、恢复集群原始状态
History     :
    1、2024-04-07 创建
"""


import os
import unittest
import time

from testcase.utils.ComThread import ComThread
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import macro
from yat.test import Node
from testcase.utils.Common import Common

Primary_SH = CommonSH('PrimaryDbUser')
Primary_ROOTSH = CommonSH('PrimaryRoot')

@unittest.skipIf(3 != Primary_SH.get_node_num(), '非1+2环境不执行')
class SharedStorage(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.com = Common()
        self.primaryRoot = Node('PrimaryRoot')
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()

    def test_shared_storage(self):
        text = '-----step1:查看集群状态; expect:集群状态正常-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        status = Primary_ROOTSH.exec_cmd_under_root("rm -rf /data/benchmarksql-5.0/run/case3_primary.log")
        status = Primary_ROOTSH.exec_cmd_under_root("rm -rf /data/benchmarksql-5.0/run/case3_standby_1.log")
        status = Primary_ROOTSH.exec_cmd_under_root("rm -rf /data/benchmarksql-5.0/run/case3_standby_2.log")

        text = '-----step2:开始运行tpcc 120s; expect:运行成功，此处不做检查-----'
        self.log.info(text)
        primary_tpcc = ComThread(self.com.start_tpcc,
                                 args=(self.primaryRoot,'/data/benchmarksql-5.0/run',
                                       './runBenchmark.sh props_write.pg >> case3_primary.log'))
        standby1_tpcc = ComThread(self.com.start_tpcc,
                               args=(self.primaryRoot, '/data/benchmarksql-5.0/run',
                                     './runBenchmark.sh props_read2.pg >> case3_standby_1.log'))
        standby2_tpcc = ComThread(self.com.start_tpcc,
                               args=(self.primaryRoot, '/data/benchmarksql-5.0/run',
                                     './runBenchmark.sh props_read1.pg >> case3_standby_2.log'))
        primary_tpcc.setDaemon(True)
        standby1_tpcc.setDaemon(True)
        standby2_tpcc.setDaemon(True)
        primary_tpcc.start()
        standby1_tpcc.start()
        standby2_tpcc.start()
        time.sleep(5)
        status = Primary_ROOTSH.exec_cmd_under_root("grep 'socket is not closed' /data/benchmarksql-5.0/run/case3_primary.log")
        self.assertNotIn('socket is not closed', status, '主1节点断开TPCC连接' + text)
        status = Primary_ROOTSH.exec_cmd_under_root("grep 'socket is not closed' /data/benchmarksql-5.0/run/case3_standby_1.log")
        self.log.info(status)
        self.assertNotIn('socket is not closed', status, '备节点1断开TPCC连接' + text)
        status = Primary_ROOTSH.exec_cmd_under_root("grep 'socket is not closed' /data/benchmarksql-5.0/run/case3_standby_2.log")
        self.log.info(status)
        self.assertNotIn('socket is not closed', status, '备2节点断开TPCC连接' + text)
        text = '-----step3:尝试停止备节点1; expect:停止成功，备节点进入Unkown状态-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='stop', param='-n 2')
        self.log.info(status)
        self.assertIn('successfully.', status, '执行失败' + text)
        time.sleep(10)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertTrue('cluster_state   : Degraded' in status or 'cluster_state   : Unavailable' in status,
        '执行失败' + text)
        res1 = status.splitlines()[-1].split('|')[1].split('6002')[-1]
        self.assertIn('S Down    Unknown', res1, '执行失败' + text)

        text = '-----step4:查看tpcc是否存在; expect:tpcc进程运行-----'
        time.sleep(5)
        self.log.info(text)
        Primary_status = Primary_ROOTSH.exec_cmd_under_root("grep 'socket is not closed' /data/benchmarksql-5.0/run/case3_primary.log")
        self.log.info(Primary_status)
        Satdnby1_status = Primary_ROOTSH.exec_cmd_under_root("grep 'socket is not closed' /data/benchmarksql-5.0/run/case3_standby_1.log")
        self.log.info(Satdnby1_status)
        Satdnby2_status = Primary_ROOTSH.exec_cmd_under_root("grep 'socket is not closed' /data/benchmarksql-5.0/run/case3_standby_2.log")
        self.log.info(Satdnby2_status)
        self.assertNotIn('socket is not closed', Primary_status, '主节点断开TPCC连接' + text)
        self.assertIn('socket is not closed', Satdnby1_status, '备1节点未断开TPCC连接;  expect:备1节点tpcc进程断开连接')
        self.assertNotIn('socket is not closed', Satdnby2_status, '备2节点断开TPCC连接' + text)

        text = '-----step5:对节点进行重新启动； expect:节点启动成功，节点状态正常,tpcc进程不中断-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='start', param='')
        self.log.info(status)
        self.assertIn('successfully.', status, '执行失败' + text)
        time.sleep(10)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        res2 = status.splitlines()[-1].split('|')[1].split('6002')[-1]
        res3 = status.splitlines()[-1].split('|')[2].split('6003')[-1]
        self.assertIn('P Primary Normal', res1, '执行失败' + text)
        self.assertIn('S Standby Normal', res2, '执行失败' + text)
        self.assertIn('S Standby Normal', res3, '执行失败' + text)

        status = Primary_ROOTSH.exec_cmd_under_root("grep 'socket is not closed' /data/benchmarksql-5.0/run/case3_primary.log")
        self.assertNotIn('socket is not closed', status, '主节点1断开TPCC连接' + text)
        status = Primary_ROOTSH.exec_cmd_under_root("grep 'socket is not closed' /data/benchmarksql-5.0/run/case3_standby_2.log")
        self.assertNotIn('socket is not closed', status, '备节点2断开TPCC连接' + text)

    def tearDown(self):
        text = '-----step6:恢复环境为初始集群状态（不涉及主机切换，只需要尝试重启）; expect:成功-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        status = Primary_SH.check_cluster_core_status(status, wait_times=600)
        self.log.info(status)
        status = Primary_SH.exec_cm_ctl(mode='stop', param='')
        self.log.info(status)
        self.assertIn('successfully.', status, '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='start', param='')
        self.log.info(status)
        self.assertIn('successfully.', status, '执行失败' + text)

        recovery = Primary_SH.exec_cm_ctl(mode='switchover', param='-a')
        self.log.info(recovery)
        self.assertIn(self.constant.cm_switchover_success_msg, recovery,
                      '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('P Primary Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + text)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + text)
        self.assertIn('S Standby Normal',
                    status.splitlines()[-1].split('|')[2].split('6003')[-1],
                    '执行失败' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
